<?php

/**
 * Users table mapper
 *
 */
class Application_Model_NodeDb
{
    protected $_table_class;
    protected $_language;

    public function __construct()
    {
        $this->_table_class='Application_Model_DbTable_Node';

        $this->_language=Zend_Registry::get('locale')->getLocale();
    }
    
    /**
     * Returns an array with all nodes objects
     * 
     * @param bool $published
     *
     * @return array
     */
    public function fetch($published=false)
    {
        $nodes=array();
        
        $node_tbl=new $this->_table_class();
        
        if (!$published)
            $node_rows=$node_tbl->fetchAll(null,
                                            array('publish_date DESC','id DESC'));
        else 
            $node_rows=$node_tbl->fetchAll(array('published=?'=>'1'),
                                            array('publish_date DESC','id DESC'));
        
        foreach ($node_rows as $row)
        {
            $node=new Application_Model_Node($row);
            
            $nodes[]=$node;
        }
        
        return $nodes;
    }
    
    /**
     * Returns an array with nodes objects
     * 
     * @param bool $published
     *
     * @return array
     */
    public function fetchNodes($published=false)
    {
        $nodes=array();
        
        $node_tbl=new $this->_table_class();
        
        if (!$published)
            $node_rows=$node_tbl->fetchAll(array('language=?'=>$this->_language),
                                            array('publish_date DESC','id DESC'));
        else 
            $node_rows=$node_tbl->fetchAll(array('published=?'=>'1','language=?'=>$this->_language),
                                            array('publish_date DESC','id DESC'));
        
        foreach ($node_rows as $row)
        {
            $node=new Application_Model_Node($row);
            
            $nodes[]=$node;
        }
        
        return $nodes;
    }
    
    /**
     * Returns an array with nodes objects by type
     * 
     * @param string $type
     * @param bool $published
     *
     * @return array
     */
    public function fetchNodesByType($type,$published=false)
    {
        $nodes=array();
        
        $node_tbl=new $this->_table_class();
        
        if (!$published)
            $node_rows=$node_tbl->fetchAll(array('type=?'=>$type,
                                                 'language=?'=>$this->_language),
                                           array('publish_date DESC','id DESC'));
        else 
            $node_rows=$node_tbl->fetchAll(array('type=?'=>$type,
                                                 'published=?'=>'1',
                                                 'language=?'=>$this->_language),
                                            array('publish_date DESC','id DESC'));
            
        foreach ($node_rows as $row)
        {
            $node=new Application_Model_Node($row);
            
            $nodes[]=$node;
        }
        
        return $nodes;
    }
    
    /**
     * Returns an array with nodes objects by category
     * 
     * @param string $category
     * @param bool $published
     *
     * @return array
     */
    public function fetchNodesByCategory($category,$published=false)
    {
        $nodes=array();
        
        $node_tbl=new $this->_table_class();
        
        if (!$published)
            $node_rows=$node_tbl->fetchAll(array('category=?'=>$category,
                                                 'language=?'=>$this->_language),
                                            array('publish_date DESC','id DESC'));
        else 
            $node_rows=$node_tbl->fetchAll(array('category=?'=>$category,
                                                 'published=?'=>'1',
                                                 'language=?'=>$this->_language),
                                            array('publish_date DESC','id DESC'));
            
        foreach ($node_rows as $row)
        {
            $node=new Application_Model_Node($row);
            
            $nodes[]=$node;
        }
        
        return $nodes;
    }
    
    /**
     * Returns an array with nodes objects by URL alias
     * 
     * @param string $alias
     * @param bool $published
     *
     * @return array
     */
    public function fetchNodesByAlias($alias,$published=false)
    {
        $nodes=array();
        
        $node_tbl=new $this->_table_class();
        
        if (!$published)
            $node_rows=$node_tbl->fetchAll(array('url_alias=?'=>$alias,
                                                 'language=?'=>$this->_language),
                                            array('publish_date DESC','id DESC'));
        else 
            $node_rows=$node_tbl->fetchAll(array('url_alias=?'=>$alias,
                                                 'published=?'=>'1',
                                                 'language=?'=>$this->_language),
                                            array('publish_date DESC','id DESC'));
            
        foreach ($node_rows as $row)
        {
            $node=new Application_Model_Node($row);
            
            $nodes[]=$node;
        }
        
        return $nodes;
    }
    
    /**
     * Returns an array with nodes objects published on front page
     * 
     * @param bool $published
     *
     * @return array
     */
    public function fetchFrontNodes($published=false)
    {
        $nodes=array();
        
        $node_tbl=new $this->_table_class();
        
        if (!$published)
            $node_rows=$node_tbl->fetchAll(array('front=?'=>'1',
                                                 'language=?'=>$this->_language),
                                            array('publish_date DESC','id DESC'));
        else 
            $node_rows=$node_tbl->fetchAll(array('front=?'=>'1',
                                                 'published=?'=>'1',
                                                 'language=?'=>$this->_language),
                                            array('publish_date DESC','id DESC'));
            
        foreach ($node_rows as $row)
        {
            $node=new Application_Model_Node($row);
            
            $nodes[]=$node;
        }
        
        return $nodes;
    }
    
    /**
     * Return an array with nodes objects by clause
     *
     * @param array $clause
     * 
     * @return array
     */
    public function fetchNodesByClause($clause)
    {
        $nodes=array();
        
        $node_tbl=new $this->_table_class();
        
        $node_rows=$node_tbl->fetchAll(array_merge($clause,array('language=?'=>$this->_language)),
                                        array('publish_date DESC','id DESC'));
       
        foreach ($node_rows as $row)
        {
            $node=new Application_Model_Node($row);
            
            $nodes[]=$node;
        }
        
        return $nodes;
    }
    
    /**
     * Return node object by ID
     *
     * @param int $id
     * @param bool $published
     * 
     * @return object
     */
    public function fetchNodeById($id,$published=false)
    {
        $node_tbl=new $this->_table_class();
        
        if (!$published)
            $row=$node_tbl->fetchRow(array('id=?'=>$id));
        else 
            $row=$node_tbl->fetchRow(array('id=?'=>$id,'published=?'=>'1'));
            
        $node=new Application_Model_Node($row);
        
        return $node;
    }

    /**
     * Saves node data to database
     *
     * @param mixed $node
     * 
     * @return int
     */
    public function save($node,$db=null)
    {
        if (is_object($node) && ($node instanceof Application_Model_Node))
        {
            $node=$node->toArray();
        }
        
        if (is_array($node))
        {
            if (empty($db))
                $node_tbl=new $this->_table_class();
            else
                $node_tbl=new $this->_table_class(array('db' => $db));
                
            if (!empty($node['id']))
            {
                return $node_tbl->update($node,array('id=?'=>$node['id']));
            } else 
            {
                return $node_tbl->insert($node);
            }
        }
    }
    
    /**
     * Deletes node from database
     *
     * @param mixed $node
     * @return int
     */
    public function delete($node)
    {
        if (is_object($node) && ($node instanceof Application_Model_Node))
        {
            $node=$node->toArray();
        }
        
        if (is_array($node) && !empty($node['id']))
        {
            $node_tbl=new $this->_table_class();

            return $node_tbl->delete(array('id=?'=>$node['id']));
        }
    }
    
    /**
     * Returns nodes paginator
     *
     * @param int $page
     * @param int $limit
     * @param bool $published
     * 
     * @return array
     */
    public function getNodesPage($page=1,$limit=10,$published=false)
    {
        $nodes=array();
        
        $db=Zend_Registry::get('db');
        
        if (!$published)
        {
            $adapter = new Zend_Paginator_Adapter_DbSelect($db->select()
                                                              ->from(Application_Model_Node::DB_TABLE)
                                                              ->where('language=?',$this->_language)
                                                              ->order(array('publish_date DESC','id DESC')));
            
            $rowCount = $db->select()->from(Application_Model_Node::DB_TABLE)
                ->reset(Zend_Db_Select::COLUMNS)
                ->columns(new Zend_Db_Expr('COUNT(*) AS '.$db->quoteIdentifier(Zend_Paginator_Adapter_DbSelect::ROW_COUNT_COLUMN)))
                ->where('language=?',$this->_language);
        } else 
        {
            $adapter = new Zend_Paginator_Adapter_DbSelect($db->select()
                                                          ->from(Application_Model_Node::DB_TABLE)
                                                          ->where('published=?','1')
                                                          ->where('language=?',$this->_language)
                                                          ->order(array('publish_date DESC','id DESC')));
        
            $rowCount = $db->select()->from(Application_Model_Node::DB_TABLE)
                ->reset(Zend_Db_Select::COLUMNS)
                ->columns(new Zend_Db_Expr('COUNT(*) AS '.$db->quoteIdentifier(Zend_Paginator_Adapter_DbSelect::ROW_COUNT_COLUMN)))
                ->where('published=?','1')
                ->where('language=?',$this->_language);
        }
        
        $adapter->setRowCount($rowCount);
        
        $paginator = new Zend_Paginator($adapter);
        $paginator->setCurrentPageNumber((int) $page);
        $paginator->setItemCountPerPage($limit);
        
        if (count($paginator))
        {
            foreach ($paginator as $row)
            {
                $node=new Application_Model_Node($row);
            
                $nodes[]=$node;
            }
        }
        
        return array($nodes,$paginator);
    }
    
    /**
     * Returns nodes paginator by type
     *
     * @param string $type
     * @param int $page
     * @param int $limit
     * @param bool $published
     * 
     * @return array
     */
    public function getNodesPageByType($type,$page=1,$limit=10,$published=false)
    {
        $nodes=array();
        
        $db=Zend_Registry::get('db');
        
        if (!$published)
        {
            $adapter = new Zend_Paginator_Adapter_DbSelect($db->select()
                                                              ->from(Application_Model_Node::DB_TABLE)
                                                              ->where('type=?',$type)
                                                              ->where('language=?',$this->_language)
                                                              ->order(array('publish_date DESC','id DESC')));
            
            $rowCount = $db->select()->from(Application_Model_Node::DB_TABLE)
                ->reset(Zend_Db_Select::COLUMNS)
                ->columns(new Zend_Db_Expr('COUNT(*) AS '.$db->quoteIdentifier(Zend_Paginator_Adapter_DbSelect::ROW_COUNT_COLUMN)))
                ->where('type=?',$type)
                ->where('language=?',$this->_language);
        } else 
        {
            $adapter = new Zend_Paginator_Adapter_DbSelect($db->select()
                                                          ->from(Application_Model_Node::DB_TABLE)
                                                          ->where('type=?',$type)
                                                          ->where('published=?','1')
                                                          ->where('language=?',$this->_language)
                                                          ->order(array('publish_date DESC','id DESC')));
        
        $rowCount = $db->select()->from(Application_Model_Node::DB_TABLE)
            ->reset(Zend_Db_Select::COLUMNS)
            ->columns(new Zend_Db_Expr('COUNT(*) AS '.$db->quoteIdentifier(Zend_Paginator_Adapter_DbSelect::ROW_COUNT_COLUMN)))
            ->where('type=?',$type)
            ->where('published=?','1')
            ->where('language=?',$this->_language);
        }
        
        $adapter->setRowCount($rowCount);
        
        $paginator = new Zend_Paginator($adapter);
        $paginator->setCurrentPageNumber((int) $page);
        $paginator->setItemCountPerPage($limit);
        
        if (count($paginator))
        {
            foreach ($paginator as $row)
            {
                $node=new Application_Model_Node($row);
            
                $nodes[]=$node;
            }
        }
        
        return array($nodes,$paginator);
    }
    
    /**
     * Returns nodes paginator by category
     *
     * @param string $category
     * @param int $page
     * @param int $limit
     * @param bool $published
     * 
     * @return array
     */
    public function getNodesPageByCategory($category,$page=1,$limit=10,$published=false)
    {
        $nodes=array();
        
        $db=Zend_Registry::get('db');
        
        if (!$published)
        {
            $adapter = new Zend_Paginator_Adapter_DbSelect($db->select()
                                                              ->from(Application_Model_Node::DB_TABLE)
                                                              ->where('category=?',$category)
                                                              ->where('language=?',$this->_language)
                                                              ->order(array('publish_date DESC','id DESC')));
            
            $rowCount = $db->select()->from(Application_Model_Node::DB_TABLE)
                ->reset(Zend_Db_Select::COLUMNS)
                ->columns(new Zend_Db_Expr('COUNT(*) AS '.$db->quoteIdentifier(Zend_Paginator_Adapter_DbSelect::ROW_COUNT_COLUMN)))
                ->where('category=?',$category)
                ->where('language=?',$this->_language);
        } else 
        {
            $adapter = new Zend_Paginator_Adapter_DbSelect($db->select()
                                                          ->from(Application_Model_Node::DB_TABLE)
                                                          ->where('category=?',$category)
                                                          ->where('published=?','1')
                                                          ->where('language=?',$this->_language)
                                                          ->order(array('publish_date DESC','id DESC')));
        
        $rowCount = $db->select()->from(Application_Model_Node::DB_TABLE)
            ->reset(Zend_Db_Select::COLUMNS)
            ->columns(new Zend_Db_Expr('COUNT(*) AS '.$db->quoteIdentifier(Zend_Paginator_Adapter_DbSelect::ROW_COUNT_COLUMN)))
            ->where('category=?',$category)
            ->where('published=?','1')
            ->where('language=?',$this->_language);
        }
        
        $adapter->setRowCount($rowCount);
        
        $paginator = new Zend_Paginator($adapter);
        $paginator->setCurrentPageNumber((int) $page);
        $paginator->setItemCountPerPage($limit);
        
        if (count($paginator))
        {
            foreach ($paginator as $row)
            {
                $node=new Application_Model_Node($row);
            
                $nodes[]=$node;
            }
        }
        
        return array($nodes,$paginator);
    }
    
    /**
     * Returns nodes paginator by type and category
     *
     * @param string $type
     * @param string $category
     * @param int $page
     * @param int $limit
     * @param bool $published
     * 
     * @return array
     */
    public function getNodesPageByTypeAndCategory($type,$category,$page=1,$limit=10,$published=false)
    {
        $nodes=array();
        
        $db=Zend_Registry::get('db');
        
        if (!$published)
        {
            $adapter = new Zend_Paginator_Adapter_DbSelect($db->select()
                                                              ->from(Application_Model_Node::DB_TABLE)
                                                              ->where('type=?',$type)
                                                              ->where('category=?',$category)
                                                              ->where('language=?',$this->_language)
                                                              ->order(array('publish_date DESC','id DESC')));
            
            $rowCount = $db->select()->from(Application_Model_Node::DB_TABLE)
                ->reset(Zend_Db_Select::COLUMNS)
                ->columns(new Zend_Db_Expr('COUNT(*) AS '.$db->quoteIdentifier(Zend_Paginator_Adapter_DbSelect::ROW_COUNT_COLUMN)))
                ->where('type=?',$type)
                ->where('category=?',$category)
                ->where('language=?',$this->_language);
        } else 
        {
            $adapter = new Zend_Paginator_Adapter_DbSelect($db->select()
                                                          ->from(Application_Model_Node::DB_TABLE)
                                                          ->where('type=?',$type)
                                                          ->where('category=?',$category)
                                                          ->where('published=?','1')
                                                          ->where('language=?',$this->_language)
                                                          ->order(array('publish_date DESC','id DESC')));
        
            $rowCount = $db->select()->from(Application_Model_Node::DB_TABLE)
                ->reset(Zend_Db_Select::COLUMNS)
                ->columns(new Zend_Db_Expr('COUNT(*) AS '.$db->quoteIdentifier(Zend_Paginator_Adapter_DbSelect::ROW_COUNT_COLUMN)))
                ->where('type=?',$type)
                ->where('category=?',$category)
                ->where('published=?','1')
                ->where('language=?',$this->_language);
        }
        
        $adapter->setRowCount($rowCount);
        
        $paginator = new Zend_Paginator($adapter);
        $paginator->setCurrentPageNumber((int) $page);
        $paginator->setItemCountPerPage($limit);
        
        if (count($paginator))
        {
            foreach ($paginator as $row)
            {
                $node=new Application_Model_Node($row);
            
                $nodes[]=$node;
            }
        }
        
        return array($nodes,$paginator);
    }
    
     /**
     * Returns nodes paginator published on front page
     *
     * @param int $page
     * @param int $limit
     * @param bool $published
     * 
     * @return array
     */
    public function getFrontNodesPage($page=1,$limit=10,$published=false)
    {
        $nodes=array();
        
        $db=Zend_Registry::get('db');
        
        if (!$published)
        {
            $adapter = new Zend_Paginator_Adapter_DbSelect($db->select()
                                                              ->from(Application_Model_Node::DB_TABLE)
                                                              ->where('front=?','1')
                                                              ->where('language=?',$this->_language)
                                                              ->order(array('publish_date DESC','id DESC')));
            
            $rowCount = $db->select()->from(Application_Model_Node::DB_TABLE)
                ->reset(Zend_Db_Select::COLUMNS)
                ->columns(new Zend_Db_Expr('COUNT(*) AS '.$db->quoteIdentifier(Zend_Paginator_Adapter_DbSelect::ROW_COUNT_COLUMN)))
                ->where('front=?','1')
                ->where('language=?',$this->_language);
        } else 
        {
            $adapter = new Zend_Paginator_Adapter_DbSelect($db->select()
                                                          ->from(Application_Model_Node::DB_TABLE)
                                                          ->where('front=?','1')
                                                          ->where('published=?','1')
                                                          ->where('language=?',$this->_language)
                                                          ->order(array('publish_date DESC','id DESC')));
        
        $rowCount = $db->select()->from(Application_Model_Node::DB_TABLE)
            ->reset(Zend_Db_Select::COLUMNS)
            ->columns(new Zend_Db_Expr('COUNT(*) AS '.$db->quoteIdentifier(Zend_Paginator_Adapter_DbSelect::ROW_COUNT_COLUMN)))
            ->where('front=?','1')
            ->where('published=?','1')
            ->where('language=?',$this->_language);
        }
        
        $adapter->setRowCount($rowCount);
        
        $paginator = new Zend_Paginator($adapter);
        $paginator->setCurrentPageNumber((int) $page);
        $paginator->setItemCountPerPage($limit);
        
        if (count($paginator))
        {
            foreach ($paginator as $row)
            {
                $node=new Application_Model_Node($row);
            
                $nodes[]=$node;
            }
        }
        
        return array($nodes,$paginator);
    }
    
    /**
     * Returns nodes paginator by clause
     *
     * @param array $clause
     * @param int $page
     * @param int $limit
     * 
     * @return array
     */
    public function getNodesPageByClause($clause,$page=1,$limit=10)
    {
        $nodes=array();
        
        $db=Zend_Registry::get('db');

        $query=$db->select()->from(Application_Model_Node::DB_TABLE);
        
        foreach ($clause as $field=>$value)
        {
            $query->where($field,$value);
        }
        
        $query->where('language=?',$this->_language);
        
        $query->order(array('publish_date DESC','id DESC'));
        
        $adapter = new Zend_Paginator_Adapter_DbSelect($query);
        
        $rowCount = $db->select()->from(Application_Model_Node::DB_TABLE)
            ->reset(Zend_Db_Select::COLUMNS)
            ->columns(new Zend_Db_Expr('COUNT(*) AS '.$db->quoteIdentifier(Zend_Paginator_Adapter_DbSelect::ROW_COUNT_COLUMN)));
            
        foreach ($clause as $field=>$value)
        {
            $rowCount->where($field,$value);
        }
        
        $rowCount->where('language=?',$this->_language);
        
        $adapter->setRowCount($rowCount);
        
        $paginator = new Zend_Paginator($adapter);
        $paginator->setCurrentPageNumber((int) $page);
        $paginator->setItemCountPerPage($limit);
        
        if (count($paginator))
        {
            foreach ($paginator as $row)
            {
                $node=new Application_Model_Node($row);
            
                $nodes[]=$node;
            }
        }
        
        return array($nodes,$paginator);
    }
    
}

